const template = document.createElement("template");
template.innerHTML = /*html*/`
  <style>
    :host {
      --height: 25px;
      --width: 100%;
      color: #777980;
      font-size: 12px;
    }
    * {
      box-sizing: border-box;
    }
    .cascader-box {
      position: relative;
    }
    input {
      width: var(--width);
      height: var(--height);
      border: 1px solid #6722ff;
      border-radius: calc(var(--height) / 2);
      outline: none;
      background-color: transparent;
      color: #777980;
      padding: 0 10px;
    }
    .option-box {
      display: none;
      position: absolute;
      left: 0;
      top: calc(var(--height) + 5px);
      width: var(--width);
      border-radius: 10px;
      background-color: #1c1f2c;
      padding: 0 10px;
      transition: all 0.3s linear;
      z-index: 999;
    }

    ::slotted(option) {
      display: block;
      padding: 5px 0;
      border-bottom: 1px solid #2d2f3e;
    }

  </style>
  <div class="cascader-box" tabindex="1">
    <input type="text" />
    <div class="option-box">
      <slot></slot>
    </div>
  </div>
`;

export default class Cascader extends HTMLElement {
  static observedAttributes = ["customize", "placeholder", "value"];
    constructor() {
      super();
      this.options = [];
      const shadow = this.attachShadow({ mode: "closed" });
      const content = template.content.cloneNode(true);
      this.inputEl = content.querySelector("input");
      const optioneBoxEl = content.querySelector(".option-box");
      const optionesEl = this.querySelectorAll("option");
      this.inputEl.onfocus = function () {
        optioneBoxEl.style.display = "block";
      };
      optionesEl.forEach((item) => {
        this.options.push({
          value: item.value,
          label: item.innerText,
        });
        item.onclick = (e) => {
          this.initState(e.target.value)
        };
      });
      this.inputEl.onkeydown = (e) => {
        if (e.keyCode === 13) {
          this.initState(this.inputEl.value)
          optioneBoxEl.style.display = "none";
        }
      };

      this.inputEl.onblur = () => {
        setTimeout(() => {
          optioneBoxEl.style.display = "none";
          this.initState(this.inputEl.value)
        }, 200);
      };
      shadow.appendChild(content);
    }
    initState(value) {
      let rule = this.getAttribute('rule');
      let option = this.options.find(item=>{
        if(item.value === value)return true;
      })
      if(option){
        this.inputEl.value = option.label;
        this.value = option.value;
        this.dispatchEvent(
          new CustomEvent("change", {
            detail: {
              value: option.value,
            },
          })
        );
      }else if(rule && new RegExp(rule).test(value)){
        this.value = value;
        this.inputEl.value = value;
        this.dispatchEvent(
          new CustomEvent("change", {
            detail: {
              value: value,
            },
          })
        );
      }else if(rule){
        let option = this.options.find(item=>{
          return item.label === value;
        })
        if(option)return;
        
        this.inputEl.value = this.options[0].label;
        this.value = this.options[0].value;
        this.dispatchEvent(
          new CustomEvent("change", {
            detail: {
              value: this.options[0].value,
            },
          })
        );
      }else{
        this.inputEl.value = value;
        this.value = value;
        this.dispatchEvent(
          new CustomEvent("change", {
            detail: {
              value: value,
            },
          })
        );
      }
    }
    attributeChangedCallback(name, oldValue, newValue) {
      if(name === 'value'){
        this.initState(newValue);
      }
      if(name === 'customize'){
        if(newValue === 'true')this.inputEl.readonly = true;
      }
      if(name === 'placeholder'){
        this.inputEl.placeholder = newValue;
      }
    }
}


